Python之路 - 迭代器和生成器
可迭代对象 🍀
在Python中一切皆对象
迭代是重复反馈过程的活动 , 其目的通常是为了逼近所需目标或结果
可迭代对象 , 即可以按照迭代的方式进行存取数据的对象 , 在python中我们可以理解为可以用for循环遍历的对象就是可迭代对象
for循环做的那些事 : for循环是我们用来遍历一个数据集合的方法 , 其实就是根据一定的要求 (这个要求叫做’协议’ ) 进行一次次的迭代的效果 . 当我们用for循环去遍历时 , 它做的第一件事就是判断对象是否是可迭代对象 , 如果是 , 那么它就会将该对象转换成一个迭代器 , 最后利用__next__()
方法将迭代器中的内容一个接一个的取出来
可迭代对象的标志是 , 它具有__iter__()
方法
判断对象是否为可迭代对象方法如下:
1 | # 导入模块 |
迭代器 🍀
通过上面的内容已经知道for循环
有一个生成迭代器的过程 , 迭代器是啥 ?
迭代器是访问集合元素的一种方式
特点:
- 不依赖索引取值 , 访问者不需要关心迭代器内部的结构 , 仅需通过next()方法去访问
- 不能随机访问集合中的某个值 , 只能从头到尾依次访问 , 不可返回访问
- 惰性计算 , 只有在需要访问时才会生成值 , 节省内存
在python中有一个iter()
方法 , 作用就是将可迭代对象变成一个迭代器 , 实质上iter()是去调用了__iter__()
方法 , 看代码:
1 | 'lyon'] l = [ |
可迭代对象与迭代器的区别:
1 | # 用dir方法查看对象中的所有方法 |
我们可以看出迭代器比可迭代对象多出了三个方法 , 所以我们可以根据这一点来判断一个对象到底是可迭代对象还是一个迭代器
1 | # 创建一个迭代器 |
判断方法:
1 | # 导入Iterable类 |
在迭代时 , 我们需要注意迭代器中是否有值的问题 , 即当我们一直调用__next__
方法取值时 , 如果值都取完了 , 而此时我们再执行 __next__
方法 , 解释器就会抛出 StopIteration , 因为已经没有值可以取了
生成器 🍀
自定义的一个能够实现迭代器功能的就是生成器
本质: 迭代器(所以自带了__iter__
方法和__next__
不需要我们去实现
特点: 惰性运算 , 开发者自定义
生成器函数 🍀
一个函数调用时返回一个迭代器 , 那么这个函数就叫做生成器函数
利用生成器做一个range( 2.x中的xrange ) 的功能
1 | # 定义函数 |
yield的作用 : yield的作用是中断函数的执行并记录中断的位置 , 等下次重新调用这个函数时 , 就会接着上次继续执行
PS : 调用生成器函数时 , 仅仅会返回一个生成器 , 并不会执行函数的内容 , 生成器只能由next() 进行调用执行 , 实质上next()方法就是调用的__next__()
方法
yield from
1 | def func(): |
生成器应用
监听文件
1 | import time |
计算动态平均值
1 | def averager(): |
列表推导式和生成器表达式 🍀
1 | # 列表解析 |
对于推导式会有另一篇专门来写
列表推导式练习
10以内所有数的平方的列表
1 | l1=[i**2 for i in range(1,11)] |
30以内能被3整除的数的平方
1 | l2 = [i**2 for i in range(1,31) if i % 3 == 0] |
3.下面是个列表.过滤掉长度小于3的字符串,并将剩下的转换成大写字母
1 | l3 = ['alex','jesse','taibai','re','ab'] |